home *** CD-ROM | disk | FTP | other *** search
/ Languguage OS 2 / Languguage OS II Version 10-94 (Knowledge Media)(1994).ISO / gnu / calc202a.lha / calc-2.02a / calc-map.el < prev    next >
Lisp/Scheme  |  1993-06-01  |  40KB  |  1,306 lines

  1. ;; Calculator for GNU Emacs, part II [calc-map.el]
  2. ;; Copyright (C) 1990, 1991, 1992, 1993 Free Software Foundation, Inc.
  3. ;; Written by Dave Gillespie, daveg@synaptics.com.
  4.  
  5. ;; This file is part of GNU Emacs.
  6.  
  7. ;; GNU Emacs is distributed in the hope that it will be useful,
  8. ;; but WITHOUT ANY WARRANTY.  No author or distributor
  9. ;; accepts responsibility to anyone for the consequences of using it
  10. ;; or for whether it serves any particular purpose or works at all,
  11. ;; unless he says so in writing.  Refer to the GNU Emacs General Public
  12. ;; License for full details.
  13.  
  14. ;; Everyone is granted permission to copy, modify and redistribute
  15. ;; GNU Emacs, but only under the conditions described in the
  16. ;; GNU Emacs General Public License.   A copy of this license is
  17. ;; supposed to have been given to you along with GNU Emacs so you
  18. ;; can know your rights and responsibilities.  It should be in a
  19. ;; file named COPYING.  Among other things, the copyright notice
  20. ;; and this notice must be preserved on all copies.
  21.  
  22.  
  23.  
  24. ;; This file is autoloaded from calc-ext.el.
  25. (require 'calc-ext)
  26.  
  27. (require 'calc-macs)
  28.  
  29. (defun calc-Need-calc-map () nil)
  30.  
  31.  
  32. (defun calc-apply (&optional oper)
  33.   (interactive)
  34.   (calc-wrapper
  35.    (let* ((sel-mode nil)
  36.       (calc-dollar-values (mapcar 'calc-get-stack-element
  37.                       (nthcdr calc-stack-top calc-stack)))
  38.       (calc-dollar-used 0)
  39.       (oper (or oper (calc-get-operator "Apply"
  40.                         (if (math-vectorp (calc-top 1))
  41.                         (1- (length (calc-top 1)))
  42.                           -1))))
  43.       (expr (calc-top-n (1+ calc-dollar-used))))
  44.      (message "Working...")
  45.      (calc-set-command-flag 'clear-message)
  46.      (calc-enter-result (1+ calc-dollar-used)
  47.             (concat (substring "apl" 0 (- 4 (length (nth 2 oper))))
  48.                 (nth 2 oper))
  49.             (list 'calcFunc-apply
  50.                   (math-calcFunc-to-var (nth 1 oper))
  51.                   expr))))
  52. )
  53.  
  54. (defun calc-reduce (&optional oper accum)
  55.   (interactive)
  56.   (calc-wrapper
  57.    (let* ((sel-mode nil)
  58.       (nest (calc-is-hyperbolic))
  59.       (rev (calc-is-inverse))
  60.       (nargs (if (and nest (not rev)) 2 1))
  61.       (calc-dollar-values (mapcar 'calc-get-stack-element
  62.                       (nthcdr calc-stack-top calc-stack)))
  63.       (calc-dollar-used 0)
  64.       (calc-mapping-dir (and (not accum) (not nest) ""))
  65.       (oper (or oper (calc-get-operator
  66.               (if nest
  67.                   (concat (if accum "Accumulate " "")
  68.                       (if rev "Fixed Point" "Nest"))
  69.                 (concat (if rev "Inv " "")
  70.                     (if accum "Accumulate" "Reduce")))
  71.               (if nest 1 2)))))
  72.      (message "Working...")
  73.      (calc-set-command-flag 'clear-message)
  74.      (calc-enter-result (+ calc-dollar-used nargs)
  75.             (concat (substring (if nest
  76.                            (if rev "fxp" "nst")
  77.                          (if accum "acc" "red"))
  78.                        0 (- 4 (length (nth 2 oper))))
  79.                 (nth 2 oper))
  80.             (if nest
  81.                 (cons (if rev
  82.                       (if accum 'calcFunc-afixp 'calcFunc-fixp)
  83.                     (if accum 'calcFunc-anest 'calcFunc-nest))
  84.                   (cons (math-calcFunc-to-var (nth 1 oper))
  85.                     (calc-top-list-n
  86.                      nargs (1+ calc-dollar-used))))
  87.               (list (if accum
  88.                     (if rev 'calcFunc-raccum 'calcFunc-accum)
  89.                   (intern (concat "calcFunc-"
  90.                           (if rev "r" "")
  91.                           "reduce"
  92.                           calc-mapping-dir)))
  93.                 (math-calcFunc-to-var (nth 1 oper))
  94.                 (calc-top-n (1+ calc-dollar-used)))))))
  95. )
  96.  
  97. (defun calc-accumulate (&optional oper)
  98.   (interactive)
  99.   (calc-reduce oper t)
  100. )
  101.  
  102. (defun calc-map (&optional oper)
  103.   (interactive)
  104.   (calc-wrapper
  105.    (let* ((sel-mode nil)
  106.       (calc-dollar-values (mapcar 'calc-get-stack-element
  107.                       (nthcdr calc-stack-top calc-stack)))
  108.       (calc-dollar-used 0)
  109.       (calc-mapping-dir "")
  110.       (oper (or oper (calc-get-operator "Map")))
  111.       (nargs (car oper)))
  112.      (message "Working...")
  113.      (calc-set-command-flag 'clear-message)
  114.      (calc-enter-result (+ nargs calc-dollar-used)
  115.             (concat (substring "map" 0 (- 4 (length (nth 2 oper))))
  116.                 (nth 2 oper))
  117.             (cons (intern (concat "calcFunc-map" calc-mapping-dir))
  118.                   (cons (math-calcFunc-to-var (nth 1 oper))
  119.                     (calc-top-list-n
  120.                      nargs
  121.                      (1+ calc-dollar-used)))))))
  122. )
  123.  
  124. (defun calc-map-equation (&optional oper)
  125.   (interactive)
  126.   (calc-wrapper
  127.    (let* ((sel-mode nil)
  128.       (calc-dollar-values (mapcar 'calc-get-stack-element
  129.                       (nthcdr calc-stack-top calc-stack)))
  130.       (calc-dollar-used 0)
  131.       (oper (or oper (calc-get-operator "Map-equation")))
  132.       (nargs (car oper)))
  133.      (message "Working...")
  134.      (calc-set-command-flag 'clear-message)
  135.      (calc-enter-result (+ nargs calc-dollar-used)
  136.             (concat (substring "map" 0 (- 4 (length (nth 2 oper))))
  137.                 (nth 2 oper))
  138.             (cons (if (calc-is-inverse)
  139.                   'calcFunc-mapeqr
  140.                 (if (calc-is-hyperbolic)
  141.                     'calcFunc-mapeqp 'calcFunc-mapeq))
  142.                   (cons (math-calcFunc-to-var (nth 1 oper))
  143.                     (calc-top-list-n
  144.                      nargs
  145.                      (1+ calc-dollar-used)))))))
  146. )
  147.  
  148. (defun calc-map-stack ()
  149.   "This is meant to be called by calc-keypad mode."
  150.   (interactive)
  151.   (let ((calc-verify-arglist nil))
  152.     (setq unread-command-char ?\$)
  153.     (calc-map))
  154. )
  155.  
  156. (defun calc-outer-product (&optional oper)
  157.   (interactive)
  158.   (calc-wrapper
  159.    (let* ((sel-mode nil)
  160.       (calc-dollar-values (mapcar 'calc-get-stack-element
  161.                       (nthcdr calc-stack-top calc-stack)))
  162.       (calc-dollar-used 0)
  163.       (oper (or oper (calc-get-operator "Outer" 2))))
  164.      (message "Working...")
  165.      (calc-set-command-flag 'clear-message)
  166.      (calc-enter-result (+ 2 calc-dollar-used)
  167.             (concat (substring "out" 0 (- 4 (length (nth 2 oper))))
  168.                 (nth 2 oper))
  169.             (cons 'calcFunc-outer
  170.                   (cons (math-calcFunc-to-var (nth 1 oper))
  171.                     (calc-top-list-n
  172.                      2 (1+ calc-dollar-used)))))))
  173. )
  174.  
  175. (defun calc-inner-product (&optional mul-oper add-oper)
  176.   (interactive)
  177.   (calc-wrapper
  178.    (let* ((sel-mode nil)
  179.       (calc-dollar-values (mapcar 'calc-get-stack-element
  180.                       (nthcdr calc-stack-top calc-stack)))
  181.       (calc-dollar-used 0)
  182.       (mul-oper (or mul-oper (calc-get-operator "Inner (Mult)" 2)))
  183.       (mul-used calc-dollar-used)
  184.       (calc-dollar-values (if (> mul-used 0)
  185.                   (cdr calc-dollar-values)
  186.                 calc-dollar-values))
  187.       (calc-dollar-used 0)
  188.       (add-oper (or add-oper (calc-get-operator "Inner (Add)" 2))))
  189.      (message "Working...")
  190.      (calc-set-command-flag 'clear-message)
  191.      (calc-enter-result (+ 2 mul-used calc-dollar-used)
  192.             (concat "in"
  193.                 (substring (nth 2 mul-oper) 0 1)
  194.                 (substring (nth 2 add-oper) 0 1))
  195.             (nconc (list 'calcFunc-inner
  196.                      (math-calcFunc-to-var (nth 1 mul-oper))
  197.                      (math-calcFunc-to-var (nth 1 add-oper)))
  198.                    (calc-top-list-n
  199.                 2 (+ 1 mul-used calc-dollar-used))))))
  200. )
  201.  
  202. ;;; Return a list of the form (nargs func name)
  203. (defun calc-get-operator (msg &optional nargs)
  204.   (setq calc-aborted-prefix nil)
  205.   (let ((inv nil) (hyp nil) (prefix nil) (forcenargs nil)
  206.     done key oper (which 0)
  207.     (msgs '( "(Press ? for help)"
  208.          "+, -, *, /, ^, %, \\, :, &, !, |, Neg"
  209.          "SHIFT + Abs, conJ, arG; maX, miN; Floor, Round; sQrt"
  210.          "SHIFT + Inv, Hyp; Sin, Cos, Tan; Exp, Ln, logB"
  211.          "Algebra + Simp, Esimp, Deriv, Integ, !, =, etc."
  212.          "Binary + And, Or, Xor, Diff; l/r/t/L/R shifts; Not, Clip"
  213.          "Conversions + Deg, Rad, HMS; Float; SHIFT + Fraction"
  214.          "Functions + Re, Im; Hypot; Mant, Expon, Scale; etc."
  215.          "Kombinatorics + Dfact, Lcm, Gcd, Choose; Random; etc."
  216.          "Time/date + newYear, Incmonth, etc."
  217.          "Vectors + Length, Row, Col, Diag, Mask, etc."
  218.          "_ = mapr/reducea, : = mapc/reduced, = = reducer"
  219.          "X or Z = any function by name; ' = alg entry; $ = stack")))
  220.     (while (not done)
  221.       (message "%s%s: %s: %s%s%s"
  222.            msg
  223.            (cond ((equal calc-mapping-dir "r") " rows")
  224.              ((equal calc-mapping-dir "c") " columns")
  225.              ((equal calc-mapping-dir "a") " across")
  226.              ((equal calc-mapping-dir "d") " down")
  227.              (t ""))
  228.            (if forcenargs
  229.            (format "(%d arg%s)"
  230.                forcenargs (if (= forcenargs 1) "" "s"))
  231.          (nth which msgs))
  232.            (if inv "Inv " "") (if hyp "Hyp " "")
  233.            (if prefix (concat (char-to-string prefix) "-") ""))
  234.       (setq key (read-char))
  235.       (if (>= key 128) (setq key (- key 128)))
  236.       (cond ((memq key '(?\C-g ?q))
  237.          (keyboard-quit))
  238.         ((memq key '(?\C-u ?\e)))
  239.         ((= key ??)
  240.          (setq which (% (1+ which) (length msgs))))
  241.         ((and (= key ?I) (null prefix))
  242.          (setq inv (not inv)))
  243.         ((and (= key ?H) (null prefix))
  244.          (setq hyp (not hyp)))
  245.         ((and (eq key prefix) (not (eq key ?v)))
  246.          (setq prefix nil))
  247.         ((and (memq key '(?a ?b ?c ?f ?k ?s ?t ?u ?v ?V))
  248.           (null prefix))
  249.          (setq prefix (downcase key)))
  250.         ((and (eq key ?\=) (null prefix))
  251.          (if calc-mapping-dir
  252.          (setq calc-mapping-dir (if (equal calc-mapping-dir "r")
  253.                         "" "r"))
  254.            (beep)))
  255.         ((and (eq key ?\_) (null prefix))
  256.          (if calc-mapping-dir
  257.          (if (string-match "map$" msg)
  258.              (setq calc-mapping-dir (if (equal calc-mapping-dir "r")
  259.                         "" "r"))
  260.            (setq calc-mapping-dir (if (equal calc-mapping-dir "a")
  261.                           "" "a")))
  262.            (beep)))
  263.         ((and (eq key ?\:) (null prefix))
  264.          (if calc-mapping-dir
  265.          (if (string-match "map$" msg)
  266.              (setq calc-mapping-dir (if (equal calc-mapping-dir "c")
  267.                         "" "c"))
  268.            (setq calc-mapping-dir (if (equal calc-mapping-dir "d")
  269.                           "" "d")))
  270.            (beep)))
  271.         ((and (>= key ?0) (<= key ?9) (null prefix))
  272.          (setq forcenargs (if (eq forcenargs (- key ?0)) nil (- key ?0)))
  273.          (and nargs forcenargs (/= nargs forcenargs) (>= nargs 0)
  274.           (error "Must be a %d-argument operator" nargs)))
  275.         ((memq key '(?\$ ?\'))
  276.          (let* ((arglist nil)
  277.             (has-args nil)
  278.             (record-entry nil)
  279.             (expr (if (eq key ?\$)
  280.                   (progn
  281.                 (setq calc-dollar-used 1)
  282.                 (if calc-dollar-values
  283.                     (car calc-dollar-values)
  284.                   (error "Stack underflow")))
  285.                 (let* ((calc-dollar-values calc-arg-values)
  286.                    (calc-dollar-used 0)
  287.                    (calc-hashes-used 0)
  288.                    (func (calc-do-alg-entry "" "Function: ")))
  289.                   (setq record-entry t)
  290.                   (or (= (length func) 1)
  291.                   (error "Bad format"))
  292.                   (if (> calc-dollar-used 0)
  293.                   (progn
  294.                     (setq has-args calc-dollar-used
  295.                       arglist (calc-invent-args has-args))
  296.                     (math-multi-subst (car func)
  297.                               (reverse arglist)
  298.                               arglist))
  299.                 (if (> calc-hashes-used 0)
  300.                     (setq has-args calc-hashes-used
  301.                       arglist (calc-invent-args has-args)))
  302.                 (car func))))))
  303.            (if (eq (car-safe expr) 'calcFunc-lambda)
  304.            (setq oper (list "$" (- (length expr) 2) expr)
  305.              done t)
  306.          (or has-args
  307.              (progn
  308.                (calc-default-formula-arglist expr)
  309.                (setq record-entry t
  310.                  arglist (sort arglist 'string-lessp))
  311.                (if calc-verify-arglist
  312.                (setq arglist (read-from-minibuffer
  313.                       "Function argument list: "
  314.                       (if arglist
  315.                           (prin1-to-string arglist)
  316.                         "()")
  317.                       minibuffer-local-map
  318.                       t)))
  319.                (setq arglist (mapcar (function
  320.                           (lambda (x)
  321.                         (list 'var
  322.                               x
  323.                               (intern
  324.                                (concat
  325.                             "var-"
  326.                             (symbol-name x))))))
  327.                          arglist))))
  328.          (setq oper (list "$"
  329.                   (length arglist)
  330.                   (append '(calcFunc-lambda) arglist
  331.                       (list expr)))
  332.                done t))
  333.            (if record-entry
  334.            (calc-record (nth 2 oper) "oper"))))
  335.         ((setq oper (assq key (nth (if inv (if hyp 3 1) (if hyp 2 0))
  336.                        (if prefix
  337.                        (symbol-value
  338.                         (intern (format "calc-%c-oper-keys"
  339.                                 prefix)))
  340.                      calc-oper-keys))))
  341.          (if (eq (nth 1 oper) 'user)
  342.          (let ((func (intern
  343.                   (completing-read "Function name: "
  344.                            obarray 'fboundp
  345.                            nil "calcFunc-"))))
  346.            (if (or forcenargs nargs)
  347.                (setq oper (list "z" (or forcenargs nargs) func)
  348.                  done t)
  349.              (if (fboundp func)
  350.              (let* ((defn (symbol-function func)))
  351.                (and (symbolp defn)
  352.                 (setq defn (symbol-function defn)))
  353.                (if (eq (car-safe defn) 'lambda)
  354.                    (let ((args (nth 1 defn))
  355.                      (nargs 0))
  356.                  (while (not (memq (car args) '(&optional
  357.                                 &rest nil)))
  358.                    (setq nargs (1+ nargs)
  359.                      args (cdr args)))
  360.                  (setq oper (list "z" nargs func)
  361.                        done t))
  362.                  (error
  363.                   "Function is not suitable for this operation")))
  364.                (message "Number of arguments: ")
  365.                (let ((nargs (read-char)))
  366.              (if (and (>= nargs ?0) (<= nargs ?9))
  367.                  (setq oper (list "z" (- nargs ?0) func)
  368.                    done t)
  369.                (beep))))))
  370.            (if (or (and (eq prefix ?v) (memq key '(?A ?I ?M ?O ?R ?U)))
  371.                (and (eq prefix ?a) (eq key ?M)))
  372.            (let* ((dir (cond ((and (equal calc-mapping-dir "")
  373.                        (string-match "map$" msg))
  374.                       (setq calc-mapping-dir "r")
  375.                       " rows")
  376.                      ((equal calc-mapping-dir "r") " rows")
  377.                      ((equal calc-mapping-dir "c") " columns")
  378.                      ((equal calc-mapping-dir "a") " across")
  379.                      ((equal calc-mapping-dir "d") " down")
  380.                      (t "")))
  381.               (calc-mapping-dir (and (memq (nth 2 oper)
  382.                                '(calcFunc-map
  383.                              calcFunc-reduce
  384.                              calcFunc-rreduce))
  385.                          ""))
  386.               (oper2 (calc-get-operator
  387.                   (format "%s%s, %s%s" msg dir
  388.                       (substring (symbol-name (nth 2 oper))
  389.                              9)
  390.                       (if (eq key ?I) " (mult)" ""))
  391.                   (cdr (assq (nth 2 oper)
  392.                          '((calcFunc-reduce  . 2)
  393.                            (calcFunc-rreduce . 2)
  394.                            (calcFunc-accum   . 2)
  395.                            (calcFunc-raccum  . 2)
  396.                            (calcFunc-nest    . 2)
  397.                            (calcFunc-anest   . 2)
  398.                            (calcFunc-fixp    . 2)
  399.                            (calcFunc-afixp   . 2))))))
  400.               (oper3 (if (eq (nth 2 oper) 'calcFunc-inner)
  401.                      (calc-get-operator
  402.                       (format "%s%s, inner (add)" msg dir
  403.                           (substring
  404.                            (symbol-name (nth 2 oper))
  405.                            9)))
  406.                    '(0 0 0)))
  407.               (args nil)
  408.               (nargs (if (> (nth 1 oper) 0)
  409.                      (nth 1 oper)
  410.                    (car oper2)))
  411.               (n nargs)
  412.               (p calc-arg-values))
  413.              (while (and p (> n 0))
  414.                (or (math-expr-contains (nth 1 oper2) (car p))
  415.                (math-expr-contains (nth 1 oper3) (car p))
  416.                (setq args (nconc args (list (car p)))
  417.                  n (1- n)))
  418.                (setq p (cdr p)))
  419.              (setq oper (list "" nargs
  420.                       (append
  421.                        '(calcFunc-lambda)
  422.                        args
  423.                        (list (math-build-call
  424.                           (intern
  425.                            (concat
  426.                         (symbol-name (nth 2 oper))
  427.                         calc-mapping-dir))
  428.                           (cons (math-calcFunc-to-var
  429.                              (nth 1 oper2))
  430.                             (if (eq key ?I)
  431.                             (cons
  432.                              (math-calcFunc-to-var
  433.                               (nth 1 oper3))
  434.                              args)
  435.                               args))))))
  436.                done t))
  437.          (setq done t))))
  438.         (t (beep))))
  439.     (and nargs (>= nargs 0)
  440.      (/= nargs (nth 1 oper))
  441.      (error "Must be a %d-argument operator" nargs))
  442.     (append (if forcenargs
  443.         (cons forcenargs (cdr (cdr oper)))
  444.           (cdr oper))
  445.         (list
  446.          (let ((name (concat (if inv "I" "") (if hyp "H" "")
  447.                  (if prefix (char-to-string prefix) "")
  448.                  (char-to-string key))))
  449.            (if (> (length name) 3)
  450.            (substring name 0 3)
  451.          name)))))
  452. )
  453. (setq calc-verify-arglist t)
  454. (setq calc-mapping-dir nil)
  455.  
  456. (defconst calc-oper-keys '( ( ( ?+ 2 calcFunc-add )
  457.                   ( ?- 2 calcFunc-sub )
  458.                   ( ?* 2 calcFunc-mul )
  459.                   ( ?/ 2 calcFunc-div )
  460.                   ( ?^ 2 calcFunc-pow )
  461.                   ( ?| 2 calcFunc-vconcat )
  462.                   ( ?% 2 calcFunc-mod )
  463.                   ( ?\\ 2 calcFunc-idiv )
  464.                   ( ?! 1 calcFunc-fact )
  465.                   ( ?& 1 calcFunc-inv )
  466.                   ( ?n 1 calcFunc-neg )
  467.                   ( ?x user )
  468.                   ( ?z user )
  469.                   ( ?A 1 calcFunc-abs )
  470.                   ( ?J 1 calcFunc-conj )
  471.                   ( ?G 1 calcFunc-arg )
  472.                   ( ?Q 1 calcFunc-sqrt )
  473.                   ( ?N 2 calcFunc-min )
  474.                   ( ?X 2 calcFunc-max )
  475.                   ( ?F 1 calcFunc-floor )
  476.                   ( ?R 1 calcFunc-round )
  477.                   ( ?S 1 calcFunc-sin )
  478.                   ( ?C 1 calcFunc-cos )
  479.                   ( ?T 1 calcFunc-tan )
  480.                   ( ?L 1 calcFunc-ln )
  481.                   ( ?E 1 calcFunc-exp )
  482.                   ( ?B 2 calcFunc-log ) )
  483.                 ( ( ?F 1 calcFunc-ceil )     ; inverse
  484.                   ( ?R 1 calcFunc-trunc )
  485.                   ( ?Q 1 calcFunc-sqr )
  486.                   ( ?S 1 calcFunc-arcsin )
  487.                   ( ?C 1 calcFunc-arccos )
  488.                   ( ?T 1 calcFunc-arctan )
  489.                   ( ?L 1 calcFunc-exp )
  490.                   ( ?E 1 calcFunc-ln )
  491.                   ( ?B 2 calcFunc-alog )
  492.                   ( ?^ 2 calcFunc-nroot )
  493.                   ( ?| 2 calcFunc-vconcatrev ) )
  494.                 ( ( ?F 1 calcFunc-ffloor )   ; hyperbolic
  495.                   ( ?R 1 calcFunc-fround )
  496.                   ( ?S 1 calcFunc-sinh )
  497.                   ( ?C 1 calcFunc-cosh )
  498.                   ( ?T 1 calcFunc-tanh )
  499.                   ( ?L 1 calcFunc-log10 )
  500.                   ( ?E 1 calcFunc-exp10 )
  501.                   ( ?| 2 calcFunc-append ) )
  502.                 ( ( ?F 1 calcFunc-fceil )    ; inverse-hyperbolic
  503.                   ( ?R 1 calcFunc-ftrunc )
  504.                   ( ?S 1 calcFunc-arcsinh )
  505.                   ( ?C 1 calcFunc-arccosh )
  506.                   ( ?T 1 calcFunc-arctanh )
  507.                   ( ?L 1 calcFunc-exp10 )
  508.                   ( ?E 1 calcFunc-log10 )
  509.                   ( ?| 2 calcFunc-appendrev ) )
  510. ))
  511. (defconst calc-a-oper-keys '( ( ( ?a 3 calcFunc-apart )
  512.                 ( ?b 3 calcFunc-subst )
  513.                 ( ?c 2 calcFunc-collect )
  514.                 ( ?d 2 calcFunc-deriv )
  515.                 ( ?e 1 calcFunc-esimplify )
  516.                 ( ?f 2 calcFunc-factor )
  517.                 ( ?g 2 calcFunc-pgcd )
  518.                 ( ?i 2 calcFunc-integ )
  519.                 ( ?m 2 calcFunc-match )
  520.                 ( ?n 1 calcFunc-nrat )
  521.                 ( ?r 2 calcFunc-rewrite )
  522.                 ( ?s 1 calcFunc-simplify )
  523.                 ( ?t 3 calcFunc-taylor )
  524.                 ( ?x 1 calcFunc-expand )
  525.                 ( ?M 2 calcFunc-mapeq )
  526.                 ( ?N 3 calcFunc-minimize )
  527.                 ( ?P 2 calcFunc-roots )
  528.                 ( ?R 3 calcFunc-root )
  529.                 ( ?S 2 calcFunc-solve )
  530.                 ( ?T 4 calcFunc-table )
  531.                 ( ?X 3 calcFunc-maximize )
  532.                 ( ?= 2 calcFunc-eq )
  533.                 ( ?\# 2 calcFunc-neq )
  534.                 ( ?< 2 calcFunc-lt )
  535.                 ( ?> 2 calcFunc-gt )
  536.                 ( ?\[ 2 calcFunc-leq )
  537.                 ( ?\] 2 calcFunc-geq )
  538.                 ( ?{ 2 calcFunc-in )
  539.                 ( ?! 1 calcFunc-lnot )
  540.                 ( ?& 2 calcFunc-land )
  541.                 ( ?\| 2 calcFunc-lor )
  542.                 ( ?: 3 calcFunc-if )
  543.                 ( ?. 2 calcFunc-rmeq )
  544.                 ( ?+ 4 calcFunc-sum )
  545.                 ( ?- 4 calcFunc-asum )
  546.                 ( ?* 4 calcFunc-prod )
  547.                 ( ?_ 2 calcFunc-subscr )
  548.                 ( ?\\ 2 calcFunc-pdiv )
  549.                 ( ?% 2 calcFunc-prem )
  550.                 ( ?/ 2 calcFunc-pdivrem ) )
  551.                   ( ( ?m 2 calcFunc-matchnot )
  552.                 ( ?M 2 calcFunc-mapeqr )
  553.                 ( ?S 2 calcFunc-finv ) )
  554.                   ( ( ?d 2 calcFunc-tderiv )
  555.                 ( ?f 2 calcFunc-factors )
  556.                 ( ?M 2 calcFunc-mapeqp )
  557.                 ( ?N 3 calcFunc-wminimize )
  558.                 ( ?R 3 calcFunc-wroot )
  559.                 ( ?S 2 calcFunc-fsolve )
  560.                 ( ?X 3 calcFunc-wmaximize )
  561.                 ( ?/ 2 calcFunc-pdivide ) )
  562.                   ( ( ?S 2 calcFunc-ffinv ) )
  563. ))
  564. (defconst calc-b-oper-keys '( ( ( ?a 2 calcFunc-and )
  565.                 ( ?o 2 calcFunc-or )
  566.                 ( ?x 2 calcFunc-xor )
  567.                 ( ?d 2 calcFunc-diff )
  568.                 ( ?n 1 calcFunc-not )
  569.                 ( ?c 1 calcFunc-clip )
  570.                 ( ?l 2 calcFunc-lsh )
  571.                 ( ?r 2 calcFunc-rsh )
  572.                 ( ?L 2 calcFunc-ash )
  573.                 ( ?R 2 calcFunc-rash )
  574.                 ( ?t 2 calcFunc-rot )
  575.                 ( ?p 1 calcFunc-vpack )
  576.                 ( ?u 1 calcFunc-vunpack )
  577.                 ( ?D 4 calcFunc-ddb )
  578.                 ( ?F 3 calcFunc-fv )
  579.                 ( ?I 1 calcFunc-irr )
  580.                 ( ?M 3 calcFunc-pmt )
  581.                 ( ?N 2 calcFunc-npv )
  582.                 ( ?P 3 calcFunc-pv )
  583.                 ( ?S 3 calcFunc-sln )
  584.                 ( ?T 3 calcFunc-rate )
  585.                 ( ?Y 4 calcFunc-syd )
  586.                 ( ?\# 3 calcFunc-nper )
  587.                 ( ?\% 2 calcFunc-relch ) )
  588.                   ( ( ?F 3 calcFunc-fvb )
  589.                 ( ?I 1 calcFunc-irrb )
  590.                 ( ?M 3 calcFunc-pmtb )
  591.                 ( ?N 2 calcFunc-npvb )
  592.                 ( ?P 3 calcFunc-pvb )
  593.                 ( ?T 3 calcFunc-rateb )
  594.                 ( ?\# 3 calcFunc-nperb ) )
  595.                   ( ( ?F 3 calcFunc-fvl )
  596.                 ( ?M 3 calcFunc-pmtl )
  597.                 ( ?P 3 calcFunc-pvl )
  598.                 ( ?T 3 calcFunc-ratel )
  599.                 ( ?\# 3 calcFunc-nperl ) )
  600. ))
  601. (defconst calc-c-oper-keys '( ( ( ?d 1 calcFunc-deg )
  602.                 ( ?r 1 calcFunc-rad )
  603.                 ( ?h 1 calcFunc-hms )
  604.                 ( ?f 1 calcFunc-float )
  605.                 ( ?F 1 calcFunc-frac ) )
  606. ))
  607. (defconst calc-f-oper-keys '( ( ( ?b 2 calcFunc-beta )
  608.                 ( ?e 1 calcFunc-erf )
  609.                 ( ?g 1 calcFunc-gamma )
  610.                 ( ?h 2 calcFunc-hypot )
  611.                 ( ?i 1 calcFunc-im )
  612.                 ( ?j 2 calcFunc-besJ )
  613.                 ( ?n 2 calcFunc-min )
  614.                 ( ?r 1 calcFunc-re )
  615.                 ( ?s 1 calcFunc-sign )
  616.                 ( ?x 2 calcFunc-max )
  617.                 ( ?y 2 calcFunc-besY )
  618.                 ( ?A 1 calcFunc-abssqr )
  619.                 ( ?B 3 calcFunc-betaI )
  620.                 ( ?E 1 calcFunc-expm1 )
  621.                 ( ?G 2 calcFunc-gammaP )
  622.                 ( ?I 2 calcFunc-ilog )
  623.                 ( ?L 1 calcFunc-lnp1 )
  624.                 ( ?M 1 calcFunc-mant )
  625.                 ( ?Q 1 calcFunc-isqrt )
  626.                 ( ?S 1 calcFunc-scf )
  627.                 ( ?T 2 calcFunc-arctan2 )
  628.                 ( ?X 1 calcFunc-xpon )
  629.                 ( ?\[ 2 calcFunc-decr )
  630.                 ( ?\] 2 calcFunc-incr ) )
  631.                   ( ( ?e 1 calcFunc-erfc )
  632.                 ( ?E 1 calcFunc-lnp1 )
  633.                 ( ?G 2 calcFunc-gammaQ )
  634.                 ( ?L 1 calcFunc-expm1 ) )
  635.                   ( ( ?B 3 calcFunc-betaB )
  636.                 ( ?G 2 calcFunc-gammag) )
  637.                   ( ( ?G 2 calcFunc-gammaG ) )
  638. ))
  639. (defconst calc-k-oper-keys '( ( ( ?b 1 calcFunc-bern )
  640.                 ( ?c 2 calcFunc-choose )
  641.                 ( ?d 1 calcFunc-dfact )
  642.                 ( ?e 1 calcFunc-euler )
  643.                 ( ?f 1 calcFunc-prfac )
  644.                 ( ?g 2 calcFunc-gcd )
  645.                 ( ?h 2 calcFunc-shuffle )
  646.                 ( ?l 2 calcFunc-lcm )
  647.                 ( ?m 1 calcFunc-moebius )
  648.                 ( ?n 1 calcFunc-nextprime )
  649.                 ( ?r 1 calcFunc-random )
  650.                 ( ?s 2 calcFunc-stir1 )
  651.                 ( ?t 1 calcFunc-totient )
  652.                 ( ?B 3 calcFunc-utpb )
  653.                 ( ?C 2 calcFunc-utpc )
  654.                 ( ?F 3 calcFunc-utpf )
  655.                 ( ?N 3 calcFunc-utpn )
  656.                 ( ?P 2 calcFunc-utpp )
  657.                 ( ?T 2 calcFunc-utpt ) )
  658.                   ( ( ?n 1 calcFunc-prevprime )
  659.                 ( ?B 3 calcFunc-ltpb )
  660.                 ( ?C 2 calcFunc-ltpc )
  661.                 ( ?F 3 calcFunc-ltpf )
  662.                 ( ?N 3 calcFunc-ltpn )
  663.                 ( ?P 2 calcFunc-ltpp )
  664.                 ( ?T 2 calcFunc-ltpt ) )
  665.                   ( ( ?b 2 calcFunc-bern )
  666.                 ( ?c 2 calcFunc-perm )
  667.                 ( ?e 2 calcFunc-euler )
  668.                 ( ?s 2 calcFunc-stir2 ) )
  669. ))
  670. (defconst calc-s-oper-keys '( ( ( ?: 2 calcFunc-assign )
  671.                 ( ?= 1 calcFunc-evalto ) )
  672. ))
  673. (defconst calc-t-oper-keys '( ( ( ?C 3 calcFunc-tzconv )
  674.                 ( ?D 1 calcFunc-date )
  675.                 ( ?I 2 calcFunc-incmonth )
  676.                 ( ?J 1 calcFunc-julian )
  677.                 ( ?M 1 calcFunc-newmonth )
  678.                 ( ?W 1 calcFunc-newweek )
  679.                 ( ?U 1 calcFunc-unixtime )
  680.                 ( ?Y 1 calcFunc-newyear ) )
  681. ))
  682. (defconst calc-u-oper-keys '( ( ( ?C 2 calcFunc-vcov )
  683.                 ( ?G 1 calcFunc-vgmean )
  684.                 ( ?M 1 calcFunc-vmean )
  685.                 ( ?N 1 calcFunc-vmin )
  686.                 ( ?S 1 calcFunc-vsdev )
  687.                 ( ?X 1 calcFunc-vmax ) )
  688.                   ( ( ?C 2 calcFunc-vpcov )
  689.                 ( ?M 1 calcFunc-vmeane )
  690.                 ( ?S 1 calcFunc-vpsdev ) )
  691.                   ( ( ?C 2 calcFunc-vcorr )
  692.                 ( ?G 1 calcFunc-agmean )
  693.                 ( ?M 1 calcFunc-vmedian )
  694.                 ( ?S 1 calcFunc-vvar ) )
  695.                   ( ( ?M 1 calcFunc-vhmean )
  696.                 ( ?S 1 calcFunc-vpvar ) )
  697. ))
  698. (defconst calc-v-oper-keys '( ( ( ?a 2 calcFunc-arrange )
  699.                 ( ?b 2 calcFunc-cvec )
  700.                 ( ?c 2 calcFunc-mcol )
  701.                 ( ?d 2 calcFunc-diag )
  702.                 ( ?e 2 calcFunc-vexp )
  703.                 ( ?f 2 calcFunc-find )
  704.                 ( ?h 1 calcFunc-head )
  705.                 ( ?k 2 calcFunc-cons )
  706.                 ( ?l 1 calcFunc-vlen )
  707.                 ( ?m 2 calcFunc-vmask )
  708.                 ( ?n 1 calcFunc-rnorm )
  709.                 ( ?p 2 calcFunc-pack )
  710.                 ( ?r 2 calcFunc-mrow )
  711.                 ( ?s 3 calcFunc-subvec )
  712.                 ( ?t 1 calcFunc-trn )
  713.                 ( ?u 1 calcFunc-unpack )
  714.                 ( ?v 1 calcFunc-rev )
  715.                 ( ?x 1 calcFunc-index )
  716.                 ( ?A 1 calcFunc-apply )
  717.                 ( ?C 1 calcFunc-cross )
  718.                 ( ?D 1 calcFunc-det )
  719.                 ( ?E 1 calcFunc-venum )
  720.                 ( ?F 1 calcFunc-vfloor )
  721.                 ( ?G 1 calcFunc-grade )
  722.                 ( ?H 2 calcFunc-histogram )
  723.                 ( ?I 2 calcFunc-inner )
  724.                 ( ?L 1 calcFunc-lud )
  725.                 ( ?M 0 calcFunc-map )
  726.                 ( ?N 1 calcFunc-cnorm )
  727.                 ( ?O 2 calcFunc-outer )
  728.                 ( ?R 1 calcFunc-reduce )
  729.                 ( ?S 1 calcFunc-sort )
  730.                 ( ?T 1 calcFunc-tr )
  731.                 ( ?U 1 calcFunc-accum )
  732.                 ( ?V 2 calcFunc-vunion )
  733.                 ( ?X 2 calcFunc-vxor )
  734.                 ( ?- 2 calcFunc-vdiff )
  735.                 ( ?^ 2 calcFunc-vint )
  736.                 ( ?~ 1 calcFunc-vcompl )
  737.                 ( ?# 1 calcFunc-vcard )
  738.                 ( ?: 1 calcFunc-vspan )
  739.                 ( ?+ 1 calcFunc-rdup ) )
  740.                   ( ( ?h 1 calcFunc-tail )
  741.                 ( ?s 3 calcFunc-rsubvec )
  742.                 ( ?G 1 calcFunc-rgrade )
  743.                 ( ?R 1 calcFunc-rreduce )
  744.                 ( ?S 1 calcFunc-rsort )
  745.                 ( ?U 1 calcFunc-raccum ) )
  746.                   ( ( ?e 3 calcFunc-vexp )
  747.                 ( ?h 1 calcFunc-rhead )
  748.                 ( ?k 2 calcFunc-rcons )
  749.                 ( ?H 3 calcFunc-histogram )
  750.                 ( ?R 2 calcFunc-nest )
  751.                 ( ?U 2 calcFunc-anest ) )
  752.                   ( ( ?h 1 calcFunc-rtail )
  753.                 ( ?R 1 calcFunc-fixp )
  754.                 ( ?U 1 calcFunc-afixp ) )
  755. ))
  756.  
  757.  
  758. ;;; Convert a variable name (as a formula) into a like-looking function name.
  759. (defun math-var-to-calcFunc (f)
  760.   (if (eq (car-safe f) 'var)
  761.       (if (fboundp (nth 2 f))
  762.       (nth 2 f)
  763.     (intern (concat "calcFunc-" (symbol-name (nth 1 f)))))
  764.     (if (memq (car-safe f) '(lambda calcFunc-lambda))
  765.     f
  766.       (math-reject-arg f "*Expected a function name")))
  767. )
  768.  
  769. ;;; Convert a function name into a like-looking variable name formula.
  770. (defun math-calcFunc-to-var (f)
  771.   (if (symbolp f)
  772.       (let* ((func (or (cdr (assq f '( ( + . calcFunc-add )
  773.                        ( - . calcFunc-sub )
  774.                        ( * . calcFunc-mul )
  775.                        ( / . calcFunc-div )
  776.                        ( ^ . calcFunc-pow )
  777.                        ( % . calcFunc-mod )
  778.                        ( neg . calcFunc-neg )
  779.                        ( | . calcFunc-vconcat ) )))
  780.                f))
  781.          (base (if (string-match "\\`calcFunc-\\(.+\\)\\'"
  782.                      (symbol-name func))
  783.                (math-match-substring (symbol-name func) 1)
  784.              (symbol-name func))))
  785.     (list 'var
  786.           (intern base)
  787.           (intern (concat "var-" base))))
  788.     f)
  789. )
  790.  
  791. ;;; Expand a function call using "lambda" notation.
  792. (defun math-build-call (f args)
  793.   (if (eq (car-safe f) 'calcFunc-lambda)
  794.       (if (= (length args) (- (length f) 2))
  795.       (math-multi-subst (nth (1- (length f)) f) (cdr f) args)
  796.     (calc-record-why "*Wrong number of arguments" f)
  797.     (cons 'calcFunc-call (cons (math-calcFunc-to-var f) args)))
  798.     (if (and (eq f 'calcFunc-neg)
  799.          (= (length args) 1))
  800.     (list 'neg (car args))
  801.       (let ((func (assq f '( ( calcFunc-add . + )
  802.                  ( calcFunc-sub . - )
  803.                  ( calcFunc-mul . * )
  804.                  ( calcFunc-div . / )
  805.                  ( calcFunc-pow . ^ )
  806.                  ( calcFunc-mod . % )
  807.                  ( calcFunc-vconcat . | ) ))))
  808.     (if (and func (= (length args) 2))
  809.         (cons (cdr func) args)
  810.       (cons f args)))))
  811. )
  812.  
  813. ;;; Do substitutions in parallel to avoid crosstalk.
  814. (defun math-multi-subst (expr olds news)
  815.   (let ((args nil)
  816.     temp)
  817.     (while (and olds news)
  818.       (setq args (cons (cons (car olds) (car news)) args)
  819.         olds (cdr olds)
  820.         news (cdr news)))
  821.     (math-multi-subst-rec expr))
  822. )
  823.  
  824. (defun math-multi-subst-rec (expr)
  825.   (cond ((setq temp (assoc expr args)) (cdr temp))
  826.     ((Math-primp expr) expr)
  827.     ((and (eq (car expr) 'calcFunc-lambda) (> (length expr) 2))
  828.      (let ((new (list (car expr)))
  829.            (args args))
  830.        (while (cdr (setq expr (cdr expr)))
  831.          (setq new (cons (car expr) new))
  832.          (if (assoc (car expr) args)
  833.          (setq args (cons (cons (car expr) (car expr)) args))))
  834.        (nreverse (cons (math-multi-subst-rec (car expr)) new))))
  835.     (t
  836.      (cons (car expr)
  837.            (mapcar 'math-multi-subst-rec (cdr expr)))))
  838. )
  839.  
  840. (defun calcFunc-call (f &rest args)
  841.   (setq args (math-build-call (math-var-to-calcFunc f) args))
  842.   (if (eq (car-safe args) 'calcFunc-call)
  843.       args
  844.     (math-normalize args))
  845. )
  846.  
  847. (defun calcFunc-apply (f args)
  848.   (or (Math-vectorp args)
  849.       (math-reject-arg args 'vectorp))
  850.   (apply 'calcFunc-call (cons f (cdr args)))
  851. )
  852.  
  853.  
  854.  
  855.  
  856. ;;; Map a function over a vector symbolically. [Public]
  857. (defun math-symb-map (f mode args)
  858.   (let* ((func (math-var-to-calcFunc f))
  859.      (nargs (length args))
  860.      (ptrs (vconcat args))
  861.      (vflags (make-vector nargs nil))
  862.      (heads '(vec))
  863.      (head nil)
  864.      (vec nil)
  865.      (i -1)
  866.      (math-working-step 0)
  867.      (math-working-step-2 nil)
  868.      len cols obj expr)
  869.     (if (eq mode 'eqn)
  870.     (setq mode 'elems
  871.           heads '(calcFunc-eq calcFunc-neq calcFunc-lt calcFunc-gt
  872.                   calcFunc-leq calcFunc-geq))
  873.       (while (and (< (setq i (1+ i)) nargs)
  874.           (not (math-matrixp (aref ptrs i)))))
  875.       (if (< i nargs)
  876.       (if (eq mode 'elems)
  877.           (setq func (list 'lambda '(&rest x)
  878.                    (list 'math-symb-map
  879.                      (list 'quote f) '(quote elems) 'x))
  880.             mode 'rows)
  881.         (if (eq mode 'cols)
  882.         (while (< i nargs)
  883.           (if (math-matrixp (aref ptrs i))
  884.               (aset ptrs i (math-transpose (aref ptrs i))))
  885.           (setq i (1+ i)))))
  886.     (setq mode 'elems))
  887.       (setq i -1))
  888.     (while (< (setq i (1+ i)) nargs)
  889.       (setq obj (aref ptrs i))
  890.       (if (and (memq (car-safe obj) heads)
  891.            (or (eq mode 'elems)
  892.            (math-matrixp obj)))
  893.       (progn
  894.         (aset vflags i t)
  895.         (if head
  896.         (if (cdr heads)
  897.             (setq head (nth
  898.                 (aref (aref [ [0 1 2 3 4 5]
  899.                           [1 1 2 3 2 3]
  900.                           [2 2 2 1 2 1]
  901.                           [3 3 1 3 1 3]
  902.                           [4 2 2 1 4 1]
  903.                           [5 3 1 3 1 5] ]
  904.                         (- 6 (length (memq head heads))))
  905.                       (- 6 (length (memq (car obj) heads))))
  906.                 heads)))
  907.           (setq head (car obj)))
  908.         (if len
  909.         (or (= (length obj) len)
  910.             (math-dimension-error))
  911.           (setq len (length obj))))))
  912.     (or len
  913.     (if (= nargs 1)
  914.         (math-reject-arg (aref ptrs 0) 'vectorp)
  915.       (math-reject-arg nil "At least one argument must be a vector")))
  916.     (setq math-working-step-2 (1- len))
  917.     (while (> (setq len (1- len)) 0)
  918.       (setq expr nil
  919.         i -1)
  920.       (while (< (setq i (1+ i)) nargs)
  921.     (if (aref vflags i)
  922.         (progn
  923.           (aset ptrs i (cdr (aref ptrs i)))
  924.           (setq expr (nconc expr (list (car (aref ptrs i))))))
  925.       (setq expr (nconc expr (list (aref ptrs i))))))
  926.       (setq math-working-step (1+ math-working-step)
  927.         vec (cons (math-normalize (math-build-call func expr)) vec)))
  928.     (setq vec (cons head (nreverse vec)))
  929.     (if (and (eq mode 'cols) (math-matrixp vec))
  930.     (math-transpose vec)
  931.       vec))
  932. )
  933.  
  934. (defun calcFunc-map (func &rest args)
  935.   (math-symb-map func 'elems args)
  936. )
  937.  
  938. (defun calcFunc-mapr (func &rest args)
  939.   (math-symb-map func 'rows args)
  940. )
  941.  
  942. (defun calcFunc-mapc (func &rest args)
  943.   (math-symb-map func 'cols args)
  944. )
  945.  
  946. (defun calcFunc-mapa (func arg)
  947.   (if (math-matrixp arg)
  948.       (math-symb-map func 'elems (cdr (math-transpose arg)))
  949.     (math-symb-map func 'elems arg))
  950. )
  951.  
  952. (defun calcFunc-mapd (func arg)
  953.   (if (math-matrixp arg)
  954.       (math-symb-map func 'elems (cdr arg))
  955.     (math-symb-map func 'elems arg))
  956. )
  957.  
  958. (defun calcFunc-mapeq (func &rest args)
  959.   (if (and (or (equal func '(var mul var-mul))
  960.            (equal func '(var div var-div)))
  961.        (= (length args) 2))
  962.       (if (math-negp (car args))
  963.       (let ((func (nth 1 (assq (car-safe (nth 1 args))
  964.                    calc-tweak-eqn-table))))
  965.         (and func (setq args (list (car args)
  966.                        (cons func (cdr (nth 1 args)))))))
  967.     (if (math-negp (nth 1 args))
  968.         (let ((func (nth 1 (assq (car-safe (car args))
  969.                      calc-tweak-eqn-table))))
  970.           (and func (setq args (list (cons func (cdr (car args)))
  971.                      (nth 1 args))))))))
  972.   (if (or (and (equal func '(var div var-div))
  973.            (assq (car-safe (nth 1 args)) calc-tweak-eqn-table))
  974.       (equal func '(var neg var-neg))
  975.       (equal func '(var inv var-inv)))
  976.       (apply 'calcFunc-mapeqr func args)
  977.     (apply 'calcFunc-mapeqp func args))
  978. )
  979.  
  980. (defun calcFunc-mapeqr (func &rest args)
  981.   (setq args (mapcar (function (lambda (x)
  982.                  (let ((func (assq (car-safe x)
  983.                            calc-tweak-eqn-table)))
  984.                    (if func
  985.                        (cons (nth 1 func) (cdr x))
  986.                      x))))
  987.              args))
  988.   (apply 'calcFunc-mapeqp func args)
  989. )
  990.  
  991. (defun calcFunc-mapeqp (func &rest args)
  992.   (if (or (and (memq (car-safe (car args)) '(calcFunc-lt calcFunc-leq))
  993.            (memq (car-safe (nth 1 args)) '(calcFunc-gt calcFunc-geq)))
  994.       (and (memq (car-safe (car args)) '(calcFunc-gt calcFunc-geq))
  995.            (memq (car-safe (nth 1 args)) '(calcFunc-lt calcFunc-leq))))
  996.       (setq args (cons (car args)
  997.                (cons (list (nth 1 (assq (car (nth 1 args))
  998.                         calc-tweak-eqn-table))
  999.                    (nth 2 (nth 1 args))
  1000.                    (nth 1 (nth 1 args)))
  1001.                  (cdr (cdr args))))))
  1002.   (math-symb-map func 'eqn args)
  1003. )
  1004.  
  1005.  
  1006.  
  1007. ;;; Reduce a function over a vector symbolically. [Public]
  1008. (defun calcFunc-reduce (func vec)
  1009.   (if (math-matrixp vec)
  1010.       (let (expr row)
  1011.     (setq func (math-var-to-calcFunc func))
  1012.     (while (setq vec (cdr vec))
  1013.       (setq row (car vec))
  1014.       (while (setq row (cdr row))
  1015.         (setq expr (if expr
  1016.                (if (Math-numberp expr)
  1017.                    (math-normalize
  1018.                 (math-build-call func (list expr (car row))))
  1019.                  (math-build-call func (list expr (car row))))
  1020.              (car row)))))
  1021.     (math-normalize expr))
  1022.     (calcFunc-reducer func vec))
  1023. )
  1024.  
  1025. (defun calcFunc-rreduce (func vec)
  1026.   (if (math-matrixp vec)
  1027.       (let (expr row)
  1028.     (setq func (math-var-to-calcFunc func)
  1029.           vec (reverse (cdr vec)))
  1030.     (while vec
  1031.       (setq row (reverse (cdr (car vec))))
  1032.       (while row
  1033.         (setq expr (if expr
  1034.                (math-build-call func (list (car row) expr))
  1035.              (car row))
  1036.           row (cdr row)))
  1037.       (setq vec (cdr vec)))
  1038.     (math-normalize expr))
  1039.     (calcFunc-rreducer func vec))
  1040. )
  1041.  
  1042. (defun calcFunc-reducer (func vec)
  1043.   (setq func (math-var-to-calcFunc func))
  1044.   (or (math-vectorp vec)
  1045.       (math-reject-arg vec 'vectorp))
  1046.   (let ((expr (car (setq vec (cdr vec)))))
  1047.     (if expr
  1048.     (progn
  1049.       (condition-case err
  1050.           (and (symbolp func)
  1051.            (let ((lfunc (or (cdr (assq func
  1052.                            '( (calcFunc-add . math-add)
  1053.                           (calcFunc-sub . math-sub)
  1054.                           (calcFunc-mul . math-mul)
  1055.                           (calcFunc-div . math-div)
  1056.                           (calcFunc-pow . math-pow)
  1057.                           (calcFunc-mod . math-mod)
  1058.                           (calcFunc-vconcat .
  1059.                            math-concat) )))
  1060.                     lfunc)))
  1061.              (while (cdr vec)
  1062.                (setq expr (funcall lfunc expr (nth 1 vec))
  1063.                  vec (cdr vec)))))
  1064.         (error nil))
  1065.       (while (setq vec (cdr vec))
  1066.         (setq expr (math-build-call func (list expr (car vec)))))
  1067.       (math-normalize expr))
  1068.       (or (math-identity-value func)
  1069.       (math-reject-arg vec "*Vector is empty"))))
  1070. )
  1071.  
  1072. (defun math-identity-value (func)
  1073.   (cdr (assq func '( (calcFunc-add . 0) (calcFunc-sub . 0)
  1074.              (calcFunc-mul . 1) (calcFunc-div . 1)
  1075.              (calcFunc-idiv . 1) (calcFunc-fdiv . 1)
  1076.              (calcFunc-min . (var inf var-inf))
  1077.              (calcFunc-max . (neg (var inf var-inf)))
  1078.              (calcFunc-vconcat . (vec))
  1079.              (calcFunc-append . (vec)) )))
  1080. )
  1081.  
  1082. (defun calcFunc-rreducer (func vec)
  1083.   (setq func (math-var-to-calcFunc func))
  1084.   (or (math-vectorp vec)
  1085.       (math-reject-arg vec 'vectorp))
  1086.   (if (eq func 'calcFunc-sub)   ; do this in a way that looks nicer
  1087.       (let ((expr (car (setq vec (cdr vec)))))
  1088.     (if expr
  1089.         (progn
  1090.           (while (setq vec (cdr vec))
  1091.         (setq expr (math-build-call func (list expr (car vec)))
  1092.               func (if (eq func 'calcFunc-sub)
  1093.                    'calcFunc-add 'calcFunc-sub)))
  1094.           (math-normalize expr))
  1095.       0))
  1096.     (let ((expr (car (setq vec (reverse (cdr vec))))))
  1097.       (if expr
  1098.       (progn
  1099.         (while (setq vec (cdr vec))
  1100.           (setq expr (math-build-call func (list (car vec) expr))))
  1101.         (math-normalize expr))
  1102.     (or (math-identity-value func)
  1103.         (math-reject-arg vec "*Vector is empty")))))
  1104. )
  1105.  
  1106. (defun calcFunc-reducec (func vec)
  1107.   (if (math-matrixp vec)
  1108.       (calcFunc-reducer func (math-transpose vec))
  1109.     (calcFunc-reducer func vec))
  1110. )
  1111.  
  1112. (defun calcFunc-rreducec (func vec)
  1113.   (if (math-matrixp vec)
  1114.       (calcFunc-rreducer func (math-transpose vec))
  1115.     (calcFunc-rreducer func vec))
  1116. )
  1117.  
  1118. (defun calcFunc-reducea (func vec)
  1119.   (if (math-matrixp vec)
  1120.       (cons 'vec
  1121.         (mapcar (function (lambda (x) (calcFunc-reducer func x)))
  1122.             (cdr vec)))
  1123.     (calcFunc-reducer func vec))
  1124. )
  1125.  
  1126. (defun calcFunc-rreducea (func vec)
  1127.   (if (math-matrixp vec)
  1128.       (cons 'vec
  1129.         (mapcar (function (lambda (x) (calcFunc-rreducer func x)))
  1130.             (cdr vec)))
  1131.     (calcFunc-rreducer func vec))
  1132. )
  1133.  
  1134. (defun calcFunc-reduced (func vec)
  1135.   (if (math-matrixp vec)
  1136.       (cons 'vec
  1137.         (mapcar (function (lambda (x) (calcFunc-reducer func x)))
  1138.             (cdr (math-transpose vec))))
  1139.     (calcFunc-reducer func vec))
  1140. )
  1141.  
  1142. (defun calcFunc-rreduced (func vec)
  1143.   (if (math-matrixp vec)
  1144.       (cons 'vec
  1145.         (mapcar (function (lambda (x) (calcFunc-rreducer func x)))
  1146.             (cdr (math-transpose vec))))
  1147.     (calcFunc-rreducer func vec))
  1148. )
  1149.  
  1150. (defun calcFunc-accum (func vec)
  1151.   (setq func (math-var-to-calcFunc func))
  1152.   (or (math-vectorp vec)
  1153.       (math-reject-arg vec 'vectorp))
  1154.   (let* ((expr (car (setq vec (cdr vec))))
  1155.      (res (list 'vec expr)))
  1156.     (or expr
  1157.     (math-reject-arg vec "*Vector is empty"))
  1158.     (while (setq vec (cdr vec))
  1159.       (setq expr (math-build-call func (list expr (car vec)))
  1160.         res (nconc res (list expr))))
  1161.     (math-normalize res))
  1162. )
  1163.  
  1164. (defun calcFunc-raccum (func vec)
  1165.   (setq func (math-var-to-calcFunc func))
  1166.   (or (math-vectorp vec)
  1167.       (math-reject-arg vec 'vectorp))
  1168.   (let* ((expr (car (setq vec (reverse (cdr vec)))))
  1169.      (res (list expr)))
  1170.     (or expr
  1171.     (math-reject-arg vec "*Vector is empty"))
  1172.     (while (setq vec (cdr vec))
  1173.       (setq expr (math-build-call func (list (car vec) expr))
  1174.         res (cons (list expr) res)))
  1175.     (math-normalize (cons 'vec res)))
  1176. )
  1177.  
  1178.  
  1179. (defun math-nest-calls (func base iters accum tol)
  1180.   (or (symbolp tol)
  1181.       (if (math-realp tol)
  1182.       (or (math-numberp base) (math-reject-arg base 'numberp))
  1183.     (math-reject-arg tol 'realp)))
  1184.   (setq func (math-var-to-calcFunc func))
  1185.   (or (null iters)
  1186.       (if (equal iters '(var inf var-inf))
  1187.       (setq iters nil)
  1188.     (progn
  1189.       (if (math-messy-integerp iters)
  1190.           (setq iters (math-trunc iters)))
  1191.       (or (integerp iters) (math-reject-arg iters 'fixnump))
  1192.       (or (not tol) (natnump iters) (math-reject-arg iters 'fixnatnump))
  1193.       (if (< iters 0)
  1194.           (let* ((dummy '(var DummyArg var-DummyArg))
  1195.              (dummy2 '(var DummyArg2 var-DummyArg2))
  1196.              (finv (math-solve-for (math-build-call func (list dummy2))
  1197.                        dummy dummy2 nil)))
  1198.         (or finv (math-reject-arg nil "*Unable to find an inverse"))
  1199.         (if (and (= (length finv) 2)
  1200.              (equal (nth 1 finv) dummy))
  1201.             (setq func (car finv))
  1202.           (setq func (list 'calcFunc-lambda dummy finv)))
  1203.         (setq iters (- iters)))))))
  1204.   (math-with-extra-prec 1
  1205.     (let ((value base)
  1206.       (ovalue nil)
  1207.       (avalues (list base))
  1208.       (math-working-step 0)
  1209.       (math-working-step-2 iters))
  1210.       (while (and (or (null iters)
  1211.               (>= (setq iters (1- iters)) 0))
  1212.           (or (null tol)
  1213.               (null ovalue)
  1214.               (if (eq tol t)
  1215.               (not (if (and (Math-numberp value)
  1216.                     (Math-numberp ovalue))
  1217.                    (math-nearly-equal value ovalue)
  1218.                  (Math-equal value ovalue)))
  1219.             (if (math-numberp value)
  1220.                 (Math-lessp tol (math-abs (math-sub value ovalue)))
  1221.               (math-reject-arg value 'numberp)))))
  1222.     (setq ovalue value
  1223.           math-working-step (1+ math-working-step)
  1224.           value (math-normalize (math-build-call func (list value))))
  1225.     (if accum
  1226.         (setq avalues (cons value avalues))))
  1227.       (if accum
  1228.       (cons 'vec (nreverse avalues))
  1229.     value)))
  1230. )
  1231.  
  1232. (defun calcFunc-nest (func base iters)
  1233.   (math-nest-calls func base iters nil nil)
  1234. )
  1235.  
  1236. (defun calcFunc-anest (func base iters)
  1237.   (math-nest-calls func base iters t nil)
  1238. )
  1239.  
  1240. (defun calcFunc-fixp (func base &optional iters tol)
  1241.   (math-nest-calls func base iters nil (or tol t))
  1242. )
  1243.  
  1244. (defun calcFunc-afixp (func base &optional iters tol)
  1245.   (math-nest-calls func base iters t (or tol t))
  1246. )
  1247.  
  1248.  
  1249. (defun calcFunc-outer (func a b)
  1250.   (or (math-vectorp a) (math-reject-arg a 'vectorp))
  1251.   (or (math-vectorp b) (math-reject-arg b 'vectorp))
  1252.   (setq func (math-var-to-calcFunc func))
  1253.   (let ((mat nil))
  1254.     (while (setq a (cdr a))
  1255.       (setq mat (cons (cons 'vec
  1256.                 (mapcar (function (lambda (x)
  1257.                         (math-build-call func
  1258.                                  (list (car a)
  1259.                                        x))))
  1260.                     (cdr b)))
  1261.               mat)))
  1262.     (math-normalize (cons 'vec (nreverse mat))))
  1263. )
  1264.  
  1265.  
  1266. (defun calcFunc-inner (mul-func add-func a b)
  1267.   (or (math-vectorp a) (math-reject-arg a 'vectorp))
  1268.   (or (math-vectorp b) (math-reject-arg b 'vectorp))
  1269.   (if (math-matrixp a)
  1270.       (if (math-matrixp b)
  1271.       (if (= (length (nth 1 a)) (length b))
  1272.           (math-inner-mats a b)
  1273.         (math-dimension-error))
  1274.     (if (= (length (nth 1 a)) 2)
  1275.         (if (= (length a) (length b))
  1276.         (math-inner-mats a (list 'vec b))
  1277.           (math-dimension-error))
  1278.       (if (= (length (nth 1 a)) (length b))
  1279.           (math-mat-col (math-inner-mats a (math-col-matrix b))
  1280.                 1)
  1281.         (math-dimension-error))))
  1282.     (if (math-matrixp b)
  1283.     (nth 1 (math-inner-mats (list 'vec a) b))
  1284.       (calcFunc-reduce add-func (calcFunc-map mul-func a b))))
  1285. )
  1286.  
  1287. (defun math-inner-mats (a b)
  1288.   (let ((mat nil)
  1289.     (cols (length (nth 1 b)))
  1290.     row col ap bp accum)
  1291.     (while (setq a (cdr a))
  1292.       (setq col cols
  1293.         row nil)
  1294.       (while (> (setq col (1- col)) 0)
  1295.     (setq row (cons (calcFunc-reduce add-func
  1296.                      (calcFunc-map mul-func
  1297.                                (car a)
  1298.                                (math-mat-col b col)))
  1299.             row)))
  1300.       (setq mat (cons (cons 'vec row) mat)))
  1301.     (cons 'vec (nreverse mat)))
  1302. )
  1303.  
  1304.  
  1305.  
  1306.